#include "ringqueue.hpp"
#include <pthread.h>
#include "Task.hpp"
#include <unistd.h>
#include <iostream>
#include <string>

#define PNUM 2
#define CNUM 5

string opers = "+-*/%@";
void* Product(void* arg)
{
    RingQUeue<Task>* rq = static_cast<RingQUeue<Task>*>(arg);
    while(1)
    {
        int data1 = rand() % 10;
        int data2 = rand() % 10;
        char oper = opers[rand() % opers.size()];

        Task t(data1,data2,oper);
        rq->Push(t);
        cout << "thread-"<< pthread_self() % 100 << "  product: " << t.GetTaskLog() << endl;
        //sleep(1);
    }
    return nullptr;
}

void* Consume(void* arg)
{
    RingQUeue<Task>* rq = static_cast<RingQUeue<Task>*>(arg);
    while(1)
    {
        Task t = rq->Pop();
        t();
        cout << "thread-"<< pthread_self() % 100 << "  consume: " << t.GetTaskLog() << t.GetResultLog() << endl;
        sleep(1);        
    }
    return nullptr;
}

int main()
{
    srand(time(0));
    pthread_t consumer[CNUM],productor[PNUM];
    RingQUeue<Task> rq; 
    for(int i = 0; i < PNUM; i++)
    {
        pthread_create(&productor[i],nullptr,Product,(void*)&rq);
    }
    for(int i = 0; i < CNUM; i++)
    {
        pthread_create(&consumer[i],nullptr,Consume,(void*)&rq);
    }
    

    for(int i = 0; i < PNUM; i++)
    {
        pthread_join(productor[i],nullptr);
    }
    for(int i = 0; i < CNUM; i++)
    {
        pthread_join(consumer[i],nullptr);
    }
    
    return 0;
}